package evs.brp;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URI;
import java.net.UnknownHostException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ClientRequestHandler {
	
	protected Log log = LogFactory.getLog(ClientRequestHandler.class);
	
	protected Socket socket;
	protected URI uri;
	protected ObjectOutput objectOutput;
	
	public ClientRequestHandler(URI uri) throws RemotingErrorException {
		this.uri = uri;
	}
	
	public ObjectOutput connect() throws RemotingErrorException {
		
		/*
		 * create client socket
		 */
		log.info("creating socket");
		try {
			socket = new Socket(uri.getHost(), uri.getPort());
		}
		catch (UnknownHostException uhe) {
			throw new RemotingErrorException(uhe);
		}
		catch (IOException ioe) {
			throw new RemotingErrorException(ioe);
		}
		log.info("creating socket done");
		
		/*
		 * get object outputstream from socket
		 * and return it 
		 */
		log.info("getObjectOutput");
		try {
			OutputStream o = socket.getOutputStream();
			objectOutput = new ObjectOutputStream(o);
		}
		catch (IOException ioe) {
			throw new RemotingErrorException(ioe);
		}
		log.info("getObjectOutput done");
		
		return objectOutput;
	}
	
	public ObjectInput send() throws RemotingErrorException {
		
		/*
		 * flush object outputstream (send message)
		 * get object inputstream 
		 * and return it
		 */
		log.info("sending");
		try {
			objectOutput.flush();

			InputStream inputStream = socket.getInputStream();
			ObjectInput objectInput = new ObjectInputStream(inputStream);
			
			return objectInput;
		} 
		catch (IOException ioe) {
			throw new RemotingErrorException(ioe);
		}
	}

	public void destroy() throws RemotingErrorException {
		
		/*
		 * close object output stream and socket
		 */
		log.info("closing socket.");
		try {
			objectOutput.close();
			socket.close();
		} 
		catch (IOException ioe) {
			throw new RemotingErrorException(ioe);
		}
	}
	
	public URI getUri() {
		return uri;
	}
}
